/**
 * 异常：
 *      编译时异常
 *      运行时异常：当抛出异常并catch后，try代码块后面的语句就不执行了
 *                当抛出异常没有catch到，交给JVM处理，后面的语句就都不执行了
 *      异常体系：都来自Throwable 又分为 Error(错误)和 Exception(异常)
 *      Error(错误)必须处理
 *      Exception(异常)分为编译时异常（在编译时就必须处理） 和 运行时异常(Runtime Exception)
 *      catch在捕获异常时，是子类在上，父类在下。最好是不糊具体的类型，然后进行不同的业务处理
 *      finally一般用于关闭资源
 *
 *      程序崩溃时，执行完finally就结束
 *      程序被捕获到异常并catch时，还会执行finally代码块后面的代码
 */
class A{
    public static void method(){
        System.out.println("hello");
    }
}
public class Exceptions {

    public static int func3(){
        int a = 10;
        try {
            return a;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return 20;// 这里最终返回的是20
        }
    }
    public static void func(){
        func();
    }
    public static void main3(String[] args) {
        func();
    }

    public static void main2(String[] args) {
        int[] arr = {1,2,3};
        try {
            arr = null;
            System.out.println(arr[5]);// 空指针异常
        }
        catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("捕捉到数组越界异常");
        }
//        catch (NullPointerException e){
//            System.out.println("捕捉到空指针异常");
//        }
        // 可以连着写：
//        catch (ArrayIndexOutOfBoundsException | NullPointerException e){
//            System.out.println("捕捉到异常");
//        }
        finally {
            System.out.println("finally语句执行了");
        }
        System.out.println("外面的语句执行了");
    }

    public static void main1(String[] args) {
        String str = null;
        System.out.println(str.length());// 空指针异常
        System.out.println(10/0);// 算数异常

    }
}
